home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright © 1993-1997 Fabrizio Oddone
- ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
- This source code is distributed as freeware:
- you may copy, exchange, modify this code.
- You may include this code in any kind of application: freeware,
- shareware, or commercial, provided that full credits are given.
- You may not sell or distribute this code for profit.
- */
-
-
- #pragma fourbyteints on
- #include <stdlib.h>
- #pragma fourbyteints reset
- #include <string.h>
-
- #include <Limits.h>
-
- #include "UtilsSys7.h"
- #include "Conversions.h"
- #include "FabWList.h"
- #include "Independents.h"
- #include "SimResIDs.h"
-
- #include "Globals.h"
- #include "Assembler.h"
- #include "Compares.h"
- #include "Disasm.h"
- #include "Dump.h"
- #include "Main.h"
- #include "Microprogram_Ed.h"
- #include "Input.h"
- #include "Registers.h"
- #include "TrackThumb.h"
- #include "DragManSim.h"
- #include "SimUtils.h"
-
- #if defined(FabSystem7orlater)
-
-
- static ControlRef disasmVScroll;
- static WindowRef curPosW;
- static short disasmLineHeight, disasmFromTop, disasmCWidMax;
-
- static short *DisasmInstruction(const short *inst, Ptr dest, ROpcDisasmPtr instrTbl, Size TblSize);
- static void ThumbActionProc(ControlHandle control, short value);
- static pascal void DisasmActionProc(ControlHandle control, short part);
-
-
- #pragma segment Init
- /* Init_Disasm: initializes the Disassembler window */
-
- OSErr Init_Disasm(void)
- {
- FMetricRec theMetrics;
- FabWindowPtr thefabw;
- Fixed tempFix;
- WindowPtr window;
- OSErr err = appMemFullErr;
-
- gWPtr_Disasm = window = GetNewWindow(kWIND_Disasm, nil, (WindowPtr)-1L);
- if (window) {
- SetPortWindowPort(window);
- if (gPrefs.remembWind)
- if (IsOnScreenWeak(gPrefs.DisasmTopLeft))
- MoveWindow(window, gPrefs.DisasmTopLeft.h, gPrefs.DisasmTopLeft.v, false);
- if (disasmVScroll = GetNewControl(kCNTL_disasmVScroll, window)) {
- TextFont(monaco);
- TextSize(9);
- TextMode(srcCopy);
- FontMetrics(&theMetrics);
- tempFix = theMetrics.descent + theMetrics.ascent + theMetrics.leading;
- tempFix = mySwap(tempFix);
- disasmLineHeight = (short)tempFix;
- disasmFromTop = *(short *)&theMetrics.ascent;
- disasmCWidMax = *(short *)&theMetrics.widMax;
- tempFix = FixMul(theMetrics.widMax, kMaxCharsInOneDisasmLineFixed);
- tempFix = mySwap(tempFix);
- SizeWindow(window, (short)tempFix + kScrollbarWidth + kDIST_FROMLEFT,
- gPrefs.remembWind ? gPrefs.DisasmHeight :
- ((PRCT_B(window) - PRCT_T(window)) / disasmLineHeight) * disasmLineHeight, false);
- SetupVertScrollBar(window, disasmVScroll);
- SetupDisasmCtlMax(disasmVScroll);
- if (gPrefs.remembWind)
- SetControlValue(disasmVScroll, gPrefs.DisasmScrollVal);
-
- thefabw = AddWindowToList(window);
- SetActivate(thefabw, Activate_Disasm);
- SetUpdate(thefabw, Update_Disasm);
- SetGrow(thefabw, Grow_Disasm);
- SetGoAway(thefabw, CloseDisasm);
- SetContent(thefabw, Do_Disasm);
- SetGetDragRect(thefabw, getDragRectDisasm);
-
- InstallRgnHandler(thefabw, NewRgn(), RecalcDump, nil,
- toMenu(kBalloons_Dump, kBDisasm_Contents), 0, 0);
-
- ResizeObjects(window);
- RecalcGlobalCoords(thefabw);
-
- if (gDragManagerActive)
- (void) MyInstallHWindow(window);
- err = noErr;
- }
- }
- return err;
- }
-
-
- #pragma segment Main
-
- /*
- GetDisasmVScrollValue: accessor */
-
- short GetDisasmVScrollValue(void)
- {
- return GetControlValue(disasmVScroll);
- }
-
-
- void ScrollDisasmTo(short newPos)
- {
- SetControlValue(disasmVScroll, newPos);
- InvalDisasm();
- }
-
- void DisasmHome(void)
- {
- SetControlValue(disasmVScroll, GetControlMinimum(disasmVScroll));
- InvalDisasm();
- }
-
- void DisasmEnd(void)
- {
- SetControlValue(disasmVScroll, GetControlMaximum(disasmVScroll));
- InvalDisasm();
- }
-
- void DisasmPgUp(void)
- {
- DisasmActionProc(disasmVScroll, kControlPageUpPart);
- }
-
- void DisasmPgDn(void)
- {
- DisasmActionProc(disasmVScroll, kControlPageDownPart);
- }
-
- /* DisasmInstruction: disassembles an instruction, returns a pointer to
- the next one. */
-
- static short *DisasmInstruction(const short *inst, Ptr dest, ROpcDisasmPtr instrTbl, Size TblSize)
- {
- Str15 tempS;
- ROpcDisasmPtr found;
- char *tempcPtr;
- short *newpos;
- short theOperand;
-
- newpos = inst + 1; /* at least two bytes per instruction */
- tempcPtr = (char *)bsearch(inst, &instrTbl->first, TblSize, sizeof(ROpcDisasm), CompareFirstLast);
- if (tempcPtr) {
- tempcPtr -= ((char *)&instrTbl->first - (char *)instrTbl);
- found = (ROpcDisasmPtr)tempcPtr;
- *(OSType *)dest = found->instr;
- if (found->classe != kCLASS_16_0) { /* there is an operand */
- /* extra word ? */
- theOperand = (found->classe == kCLASS_16_16 || found->classe == kCLASS_16_16_REL) ?
- *newpos++ : *inst & (found->last - found->first);
- switch (found->classe) { /* sign extensions for 12 & 11 bit operands */
- case kCLASS_4_12:
- case kCLASS_4_12_REL:
- theOperand <<= 4;
- theOperand >>= 4;
- break;
- case kCLASS_5_11:
- theOperand <<= 5;
- theOperand >>= 5;
- break;
- }
- if (found->classe == kCLASS_4_12)
- ShortToHexString(theOperand, tempS);
- else
- MyNumToString(theOperand, tempS);
- tempcPtr = dest + 5;
- if (found->classe == kCLASS_4_12) /* hex value */
- *tempcPtr++ = '$';
- if (found->classe >= kCLASS_16_16_REL) { /* relative jumps */
- *tempcPtr++ = '*';
- if (theOperand > 0) /* wanna a plus sign before positive values */
- *tempcPtr++ = '+';
- }
- memcpy(tempcPtr, &tempS[1], tempS[0]);
- tempcPtr += tempS[0];
- if (found->classe >= kCLASS_16_16_REL) { /* relative jumps */
- *tempcPtr++ = ' ';
- *tempcPtr++ = '(';
- *tempcPtr++ = '$';
- tempcPtr = ShortToHexText(PTR2MEMWORD(newpos) + theOperand, tempcPtr);
- *tempcPtr++ = ')';
- }
- }
- }
- else { // illegal instruction
- *(OSType *)dest = 'ILL*';
- }
- return newpos;
- }
-
- /* Activate_Disasm: handles activate events */
-
- void Activate_Disasm(EventRecord */*evt*/, WindowPtr w, Handle, short, Boolean becomingActive)
- {
- Rect growRect;
-
- /* the growbox needs to be redrawn on activation: */
- botRight(growRect) = botRight(w->portRect);
- /* adjust for the scrollbars */
- growRect.top = growRect.bottom - kScrollbarAdjust + 1;
- growRect.left = growRect.right - kScrollbarAdjust + 1;
- InvalRect(&growRect); /* we cannot avoid grow box flicker */
- if (becomingActive) {
- if ((*disasmVScroll)->contrlVis == 0) {
- ShowControl(disasmVScroll);
- ValidRect(&(*disasmVScroll)->contrlRect);
- }
- }
- else {
- /* the control must be redrawn on deactivation: */
- HideControl(disasmVScroll);
- }
- } /*Activate*/
-
- /* Grow_Disasm: handles resizing */
-
- void Grow_Disasm(WindowPtr w, EventRecord *event)
- {
- Rect tempRect, updateRect;
- long growResult;
-
- tempRect.right = tempRect.left = PRCT_R(w) + 1;
- tempRect.bottom = SHRT_MAX; /* set up limiting values */
- tempRect.top = kMinDocDim + 30;
- updateRect = w->portRect;
- updateRect.top = updateRect.bottom - kScrollbarAdjust;
- /* see if it really changed size */
- if (growResult = GrowWindow(w, event->where, &tempRect)) {
- SizeWindow(w, LoWrd(growResult),
- (HiWrd(growResult) / disasmLineHeight) * disasmLineHeight, true);
- SizeControl(disasmVScroll, kScrollbarWidth, PRCT_B(w) - PRCT_T(w) - 13);
- if (HiWrd(growResult) > updateRect.bottom)
- /* enlarged */
- InvalRect(&updateRect);
- else /* reduced */ {
- updateRect.bottom = PRCT_B(w);
- updateRect.right = PRCT_R(w);
- updateRect.top = updateRect.bottom - kScrollbarAdjust + 1;
- updateRect.left = updateRect.right - kScrollbarAdjust + 1;
- InvalRect(&updateRect);
- }
- ValidRect(&(*disasmVScroll)->contrlRect);
- SetupDisasmCtlMax(disasmVScroll);
- }
- }
-
- /* Update_Disasm: handles window updates. */
-
- void Update_Disasm(WindowPtr w, short)
- {
- Rect growRect;
- RgnHandle oldClip;
-
- if (EmptyRgn(w->visRgn) == false) { /* draw if updating needs to be done */
- DrawDisasm(w);
- oldClip = NewRgn();
- GetClip(oldClip);
- growRect = w->portRect;
- growRect.left = growRect.right - kScrollbarAdjust;
- ClipRect(&growRect);
- DrawGrowIcon(w);
- SetClip(oldClip);
- DisposeRgn(oldClip);
- UpdateControls(w, w->visRgn);
- }
- }
-
- /* Do_Disasm: we handle mouse clicks in scrollbars */
-
- void Do_Disasm(WindowPtr w, EventRecord *event)
- {
- Rect tempRect;
- GrafPtr savePort;
- ControlHandle control;
- Point mouse;
- short part;
-
- mouse = event->where; /* get the click position */
- GlobalToLocal(&mouse);
- /* see if we are in the disasm area; if so, we won’t check the controls */
- tempRect = w->portRect;
- tempRect.right -= kScrollbarAdjust;
- //if (PtInRect(mouse, &tempRect)) {
- /* handle editing click */
- /* if ((offset = mouse.h - disasmCWidMax * 6 - kDIST_FROMLEFT) >= 0)
- if ((offset /= disasmCWidMax) % 5 != 4) {
- tempRect.top = (mouse.v /= dumpLineHeight) * dumpLineHeight;
- tempRect.left = ((offset / 5) * 5) * dumpCWidMax + dumpCWidMax * 6 + kDIST_FROMLEFT;
- tempRect.bottom = tempRect.top + dumpLineHeight;
- tempRect.right = tempRect.left + (dumpCWidMax << 2);
- if (TrackObject(&tempRect)) {
- clickAddr = ((unsigned long)(GetDumpVScrollValue() + mouse.v) << 4)
- + ((offset / 5) << 1);
- if (DoEditDump((short *)(mMemory + clickAddr), clickAddr >> 1))
- DrawDump();
- UnloadSeg(DoEditDump);
- }
- }*/
- // }
- /*else*/ {
- part = FindControl(mouse, w, &control);
- switch ( part ) {
- case 0: /* do nothing for viewRect case */
- break;
- case kControlIndicatorPart:
- GetPort(&savePort);
- curPosW = GetNewWindow(kWIND_CurPos, nil, (WindowPtr)-1L);
- SetPortWindowPort(curPosW);
- TextMode(srcCopy);
- TextFont(monaco);
- TextSize(9);
- SetPort(savePort);
- // Apple would like us not to use GhostWindow, but in this case we avoid
- // plenty of useless activate/deactivate events, so we don’t feel guilty.
-
- savePort = (GrafPtr)LMGetGhostWindow();
- LMSetGhostWindow(curPosW);
- ShowWindow(curPosW);
- (void) TrackThumb(control, mouse, ThumbActionProc);
- DisposeWindow(curPosW);
- LMSetGhostWindow(savePort);
- InvalDisasm();
- break;
- default: /* clicked in an arrow, so track & scroll */
- {
- ControlActionUPP DisasmActionProcUPP = NewControlActionProc(DisasmActionProc);
-
- (void) TrackControl(control, mouse, DisasmActionProcUPP);
- if (DisasmActionProcUPP)
- DisposeRoutineDescriptor(DisasmActionProcUPP);
- }
- break;
- }
- }
- }
-
- /* ThumbActionProc: continuously called while we drag the scroll box */
-
- static void ThumbActionProc(ControlHandle , short value)
- {
- Str15 tempS;
- GrafPtr savePort;
-
- ShortToHexString(value << 1, tempS);
- GetPort(&savePort);
- SetPort(curPosW);
- MoveTo(kDIST_FROMLEFT,12);
- DrawString(tempS);
- SetPort(savePort);
- }
-
- /* DisasmActionProc: called when we hold mouse button down in some
- parts of the scroll bar. */
-
- static pascal void DisasmActionProc(ControlHandle control, short part)
- {
- WindowPtr w;
- short amount, oldAmount;
-
- if ( part ) { /* if it was actually in the control */
- w = (*control)->contrlOwner;
- switch ( part ) {
- case kControlUpButtonPart:
- amount = -1;
- break;
- case kControlDownButtonPart:
- amount = 1;
- break;
- case kControlPageUpPart:
- amount = (PRCT_T(w) - PRCT_B(w)) / (disasmLineHeight * 2) + 1;
- break;
- case kControlPageDownPart:
- amount = (PRCT_B(w) - PRCT_T(w)) / (disasmLineHeight * 2) - 1;
- break;
- }
- SetControlValue(control, (oldAmount = GetControlValue(control)) + amount);
- if (oldAmount != GetControlValue(control))
- DrawDisasm(w);
- }
- } /* DisasmActionProc */
-
- /* DrawDisasm: redraws the entire Disassembler window */
-
- void DrawDisasm(WindowPtr w)
- {
- Str27 disassembledText;
- Rect tempRect, ToBeInverted;
- GrafPtr savePort;
- Handle tH;
- Point tempPoint;
- short *addr;
- long *clrptr;
- short *textPtr;
- long spaces = 0L;
- short j, HilitePC;
- SignedByte savedState;
-
- GetPort(&savePort);
- SetPort(w);
- savedState = WantThisHandleSafe(tH = Get1Resource(krInstructions, kOPCODES));
- tempRect = w->portRect;
- tempRect.bottom += disasmLineHeight;
- spaces = GetControlValue(disasmVScroll);
- addr = (short *)&gMMemory[spaces << 2];
- for(tempPoint.h = kDIST_FROMLEFT, j = disasmFromTop;
- tempPoint.v = j, PtInRect(tempPoint, &tempRect);
- j += disasmLineHeight) {
-
- MoveTo(PRCT_L(w) + kDIST_FROMLEFT, j);
- clrptr = (long *)&disassembledText;
- spaces = ' ';
- *clrptr++ = spaces;
- *clrptr++ = spaces;
- *clrptr++ = spaces;
- *clrptr++ = spaces;
- *clrptr++ = spaces;
- *clrptr++ = spaces;
- *clrptr = spaces;
- textPtr = (short *)ShortToHexText(HilitePC = PTR2MEMWORD(addr), (Ptr)&disassembledText);
- *textPtr++ = ': ';
- addr = DisasmInstruction(addr, (Ptr)textPtr, (ROpcDisasmPtr)((*tH) + 2), *(unsigned short *)*tH + 1);
-
- DrawText(&disassembledText, 0L, 28L);
- if (HilitePC == gRegs[kREG_PC]) {
- ToBeInverted.top = j - disasmLineHeight + 1;
- ToBeInverted.left = PRCT_L(w) + kDIST_FROMLEFT;
- ToBeInverted.bottom = j + 1;
- ToBeInverted.right = ToBeInverted.left + disasmCWidMax * kMaxCharsInOneDisasmLine;
- LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
- InvertRect(&ToBeInverted);
- }
- }
- HSetState(tH, savedState);
- SetPort(savePort);
- }
-
- /* SetupDisasmCtlMax: sets up the CtlMax value of our scroll bar */
-
- void SetupDisasmCtlMax(ControlHandle theControl)
- {
- enum {
- kAdjustForPleasantGrow = 3
- };
-
- WindowRef wind;
- short newmax;
-
- wind = (*theControl)->contrlOwner;
- newmax = SHRT_MAX - (PRCT_B(wind) - PRCT_T(wind) - kAdjustForPleasantGrow) / (disasmLineHeight << 1);
- if (newmax != GetControlMaximum(theControl)) {
- SetControlMaximum(theControl, newmax);
- InvalDisasm();
- }
- }
-
- /* InvalDisasm: invalidates the entire window contents
- (excluding the scrollbar) */
-
- void InvalDisasm(void)
- {
- Rect tempRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPortWindowPort(gWPtr_Disasm);
- tempRect = gWPtr_Disasm->portRect;
- tempRect.right -= kScrollbarWidth;
- InvalRect(&tempRect);
- SetPort(savePort);
- }
-
- /* procedure called when closing the Disasm window */
-
- void CloseDisasm(WindowPtr w)
- {
- DoCloseWindow(w, kMItem_Disasm);
- }
-
- void getDragRectDisasm(WindowPtr w, RectPtr r)
- {
- *r = w->portRect;
- r->right -= kScrollbarAdjust;
- }
-
-
- #endif
-
-